International aid may take the form of multilateral aid – provided
through international bodies such as the UN, or NGOs such as Oxfam – or
bilateral aid, which operates on a government-to-government basis. There
is considerable debate about whether international aid works, in the
sense of reducing poverty and stimulating development.
However, the effectiveness of aid is often diluted by corruption. Aid
is invariably channeled through the governments of recipient countries,
in which power is often concentrated in the hands of a few politicians
and bureaucrats, and the mechanisms of accountability are, at best,
poorly developed. This tends to benefit corrupt leaders and elites
rather than the people, projects and programs for which it was
intended.
The hypothesis that foreign aid can promote growth in developing
countries was explored, using panel data series for foreign aid, while
accounting for regional differences in Asian, African, Latin American,
and the Caribbean countries as well as the differences in income levels,
the results of this study also indicate that foreign aid has mixed
effects on economic growth in developing countries.
This study examines the relationships between foreign aid,
institutional structure, and economic performance for 80 countries in
Europe, America, Africa, and Asia. It is found that official development
assistance and the quality of institutional structure in the sample
countries affect economic growth positively.
Loading libraries
Some libraries and packages used for data manipulation and data
scrapping
library(tidyverse) # i don't think I´ll use this /r
── Attaching core tidyverse packages ───────────────────────────────────────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.1
✔ purrr 1.0.2 ── Conflicts ─────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(WDI) # for World Bank data acceding (mostly country code names)
library(readxl) # for excel files reading
library(readr) # for csv files reading
library(visdat) # for data visualization
library(plotly) # for plots
Adjuntando el paquete: ‘plotly’
The following object is masked from ‘package:ggplot2’:
last_plot
The following object is masked from ‘package:stats’:
filter
The following object is masked from ‘package:graphics’:
layout
library(purrr)
Gathering Data
Data for low income countries will be used, as categorized by the
World Bank there are 26 Low income countries and 51 Lower middle income
countries
country_class <- read_excel("CLASS.xlsx")
country_class %>%
filter(!is.na(Region), !is.na(`Income group`)) %>%
group_by(`Income group`) %>%
summarise(countries = n())
Here are listed countries to use:
my_countries <- country_class %>%
filter(!is.na(Region), `Income group` %in% c('Low income', 'Lower middle income')) %>%
select(Code)
Here we get the respective iso2c names
my_countries$iso2c <- WDI_data$country %>%
filter(iso3c %in% my_countries$Code) %>%
.$iso2c
Data from the World Bank API and the Human Development Reports API is
dowloaded by the usage of Python Scripts. They are stored as csv files
and then loaded here:
HDI
datos_HDI <- read_csv("datos_python_HDI.csv", col_names = c('Code', 'iso2c', 'indicator', 'year', 'value'),
col_types = list(col_character(), col_character(), col_character(), col_double(), col_double()))
hdi_indicators <- datos_HDI %>% distinct(indicator) %>% .$indicator
ODA
oda_indicators <- c(
'DT_ODA_ALLD_CD',
'DT_ODA_ALLD_KD',
'DT_ODA_OATL_CD',
'DT_ODA_OATL_KD',
'DT_ODA_ODAT_CD',
'DT_ODA_ODAT_GI_ZS',
'DT_ODA_ODAT_GN_ZS',
'DT_ODA_ODAT_KD',
'DT_ODA_ODAT_MP_ZS',
'DT_ODA_ODAT_PC_ZS',
'DT_ODA_ODAT_XP_ZS'
)
gob_indicators <- c(
'CC_EST',
'CC_NO_SRC',
'CC_PER_RNK',
'CC_PER_RNK_LOWER',
'CC_PER_RNK_UPPER',
'CC_STD_ERR',
'GE_EST',
'GE_NO_SRC',
'GE_PER_RNK',
'GE_PER_RNK_LOWER',
'GE_PER_RNK_UPPER',
'GE_STD_ERR',
'PV_EST',
'PV_NO_SRC',
'PV_PER_RNK',
'PV_PER_RNK_LOWER',
'PV_PER_RNK_UPPER',
'PV_STD_ERR',
'RQ_EST',
'RQ_NO_SRC',
'RQ_PER_RNK',
'RQ_PER_RNK_LOWER',
'RQ_PER_RNK_UPPER',
'RQ_STD_ERR',
'RL_EST')
datos_WB <- data.frame(indicator = character(), iso2c = character(), year = double(), value = double())
suppressWarnings(
for (indicator in c(oda_indicators, gob_indicators)) {
datos_WB <- rbind(datos_WB, read_csv(paste("datos_python", indicator, ".csv", sep =''),
col_names = c('indicator', 'iso2c', 'year', 'value'),
col_types = list(col_character(), col_character(), col_double(), col_double())))
}
)
Data Manipulation
Transform the data into a new structure for easier understanding
datos_paper <- rbind(datos_WB, datos_HDI %>% select(indicator, iso2c, year, value)) %>%
pivot_wider(names_from = indicator, values_from = value)
Lets check which data is missing…
vis_dat(datos_paper %>% select(all_of(gsub("_", ".", oda_indicators))))

# DT.ODA.OATL.CD and DT.ODA.OATL.KD missing for all countries and years
# DT.ODA.ODAT.GI.ZS, DT.ODA.ODAT.GN.ZS, DT.ODA.ODAT.MP.ZS and DT.ODA.ODAT.XP.ZS also has some missing values
# There is a couple of countries that has some missing values for some exact years



Taking into account the missing data let´s select a smaller sample to
test
Now lets view data again with those filters

From 1925 to 1098 rows huh… i don’t know…
Let’s give it a shot with a linear model
summary(model)
Call:
lm(formula = hdi ~ DT.ODA.ALLD.CD + CC.EST + GE.EST + PV.EST +
RQ.EST + RL.EST, data = datos_model)
Residuals:
Min 1Q Median 3Q Max
-0.291363 -0.060809 0.001437 0.062167 0.195139
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 5.881e-01 5.818e-03 101.081 < 2e-16 ***
DT.ODA.ALLD.CD 2.008e-12 2.589e-12 0.776 0.43815
CC.EST -6.896e-02 1.085e-02 -6.355 3.05e-10 ***
GE.EST 1.533e-01 1.107e-02 13.849 < 2e-16 ***
PV.EST 9.200e-03 4.513e-03 2.039 0.04172 *
RQ.EST -3.501e-02 1.065e-02 -3.288 0.00104 **
RL.EST 2.094e-02 1.204e-02 1.738 0.08243 .
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.08902 on 1091 degrees of freedom
Multiple R-squared: 0.2893, Adjusted R-squared: 0.2854
F-statistic: 74 on 6 and 1091 DF, p-value: < 2.2e-16
It worked!!! but I just threw random variables in there, I want to
see their relationship with HID
#Data visualization
… what was that??? I guess I cant just throw things in there and
expect to have a good model, I can’t see a clear relationship between
this stuff, more than better governance indicators are usually
accompanied with better HDI scores. But… I was saying that I wanted to
find a relationship with HDI changes, not the actual HDI score. So, I’ll
compute a HDI change per year per country, (and lose 61 rows in the
process, yay…)
Data manipulation 2 Electric boogaloo
Note: originally I was excluding data from 2001, because some
countries didn’t have governance indicators for that year particularly,
but!, since I’ll lose one year by computing the growth in hdi I can
still use this year and wont loose data al all. STONKS!!!


and here we go again
Testing model while using hdi_diff as dependent variable (it went
better than expected)
summary(model_3)
Call:
lm(formula = hdi_diff ~ DT.ODA.ALLD.CD + CC.EST + GE.EST + PV.EST +
RQ.EST + RL.EST, data = datos_model_3)
Residuals:
Min 1Q Median 3Q Max
-0.084650 -0.002575 0.000074 0.002727 0.074605
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 6.437e-03 4.444e-04 14.485 < 2e-16 ***
DT.ODA.ALLD.CD -6.826e-14 1.978e-13 -0.345 0.73005
CC.EST 6.344e-04 8.289e-04 0.765 0.44421
GE.EST 2.211e-03 8.457e-04 2.615 0.00905 **
PV.EST 1.058e-03 3.448e-04 3.070 0.00219 **
RQ.EST -1.227e-03 8.134e-04 -1.509 0.13169
RL.EST -2.355e-03 9.200e-04 -2.560 0.01060 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.006801 on 1091 degrees of freedom
Multiple R-squared: 0.01844, Adjusted R-squared: 0.01304
F-statistic: 3.416 on 6 and 1091 DF, p-value: 0.002404
I liked the relationship visible in the PER.RNK gov indicators, let’s
try a model with those variables (it went worse than expected)
summary(model_4)
Call:
lm(formula = hdi_diff ~ DT.ODA.ALLD.CD + CC.PER.RNK + GE.PER.RNK +
PV.PER.RNK + RQ.PER.RNK + RL.EST, data = datos_model_3)
Residuals:
Min 1Q Median 3Q Max
-0.085300 -0.002458 0.000048 0.002847 0.074421
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 4.239e-03 1.620e-03 2.616 0.00902 **
DT.ODA.ALLD.CD -2.927e-13 1.917e-13 -1.527 0.12711
CC.PER.RNK 2.002e-05 2.154e-05 0.930 0.35272
GE.PER.RNK 4.254e-05 2.599e-05 1.637 0.10192
PV.PER.RNK 9.925e-06 1.451e-05 0.684 0.49422
RQ.PER.RNK -3.012e-05 2.547e-05 -1.182 0.23733
RL.EST -1.296e-03 9.288e-04 -1.395 0.16323
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.006842 on 1091 degrees of freedom
Multiple R-squared: 0.006585, Adjusted R-squared: 0.001122
F-statistic: 1.205 on 6 and 1091 DF, p-value: 0.3009
LS0tDQp0aXRsZTogIk9mZmljaWFsIERldmVsb3BtZW50IEFzc2lzdGFuY2UgYW5kIEluc3RpdHV0aW9uYWwgUXVhbGl0eSBvbiBVbmRldmVsb3BlZCBjb3VudHJpZXMiDQpvdXRwdXQ6DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQpkYXRlOiAiMjAyNC0wOC0wNSINCmF1dGhvcjogIk9zY2FyIEVkdWFyZG8gTW9yYWxlcyBDw6FyZGVuYXMiDQotLS0NCg0KDQpJbnRlcm5hdGlvbmFsIGFpZCBtYXkgdGFrZSB0aGUgZm9ybSBvZiBtdWx0aWxhdGVyYWwgYWlkIOKAkyBwcm92aWRlZCB0aHJvdWdoIGludGVybmF0aW9uYWwgYm9kaWVzIHN1Y2ggYXMgdGhlIFVOLCBvciBOR09zIHN1Y2ggYXMgT3hmYW0g4oCTIG9yIGJpbGF0ZXJhbCBhaWQsIHdoaWNoIG9wZXJhdGVzIG9uIGEgZ292ZXJubWVudC10by1nb3Zlcm5tZW50IGJhc2lzLiBUaGVyZSBpcyBjb25zaWRlcmFibGUgZGViYXRlIGFib3V0IHdoZXRoZXIgaW50ZXJuYXRpb25hbCBhaWQgd29ya3MsIGluIHRoZSBzZW5zZSBvZiByZWR1Y2luZyBwb3ZlcnR5IGFuZCBzdGltdWxhdGluZyBkZXZlbG9wbWVudC4NCg0KSG93ZXZlciwgdGhlIGVmZmVjdGl2ZW5lc3Mgb2YgYWlkIGlzIG9mdGVuIGRpbHV0ZWQgYnkgY29ycnVwdGlvbi4gQWlkIGlzIGludmFyaWFibHkgY2hhbm5lbGVkIHRocm91Z2ggdGhlIGdvdmVybm1lbnRzIG9mIHJlY2lwaWVudCBjb3VudHJpZXMsIGluIHdoaWNoIHBvd2VyIGlzIG9mdGVuIGNvbmNlbnRyYXRlZCBpbiB0aGUgaGFuZHMgb2YgYSBmZXcgcG9saXRpY2lhbnMgYW5kIGJ1cmVhdWNyYXRzLCBhbmQgdGhlIG1lY2hhbmlzbXMgb2YgYWNjb3VudGFiaWxpdHkgYXJlLCBhdCBiZXN0LCBwb29ybHkgZGV2ZWxvcGVkLiBUaGlzIHRlbmRzIHRvIGJlbmVmaXQgY29ycnVwdCBsZWFkZXJzIGFuZCBlbGl0ZXMgcmF0aGVyIHRoYW4gdGhlIHBlb3BsZSwgcHJvamVjdHMgYW5kIHByb2dyYW1zIGZvciB3aGljaCBpdCB3YXMgaW50ZW5kZWQuDQoNClxiZWdpbntmbHVzaHJpZ2h0fQ0KV2F0dHMsIENhcmwuICgyMDE0KS4gUmU6IERvZXMgZm9yZWlnbiBhaWQgaGVscCB0aGUgZGV2ZWxvcGluZyBjb3VudHJpZXMgdG93YXJkcyBkZXZlbG9wbWVudD8uIFJldHJpZXZlZCBmcm9tOiAkaHR0cHM6Ly93d3cucmVzZWFyY2hnYXRlLm5ldC9wb3N0L0RvZXNfZm9yZWlnbl9haWRfaGVscF90aGVfZGV2ZWxvcGluZ19jb3VudHJpZXNfdG93YXJkc19kZXZlbG9wbWVudC81MzIyMDA1ZWQwMzliMWU3NjQ4YjQ1OWMvY2l0YXRpb24vZG93bmxvYWQuJA0KXGVuZHtmbHVzaHJpZ2h0fQ0KDQoNClRoZSBoeXBvdGhlc2lzIHRoYXQgZm9yZWlnbiBhaWQgY2FuIHByb21vdGUgZ3Jvd3RoIGluIGRldmVsb3BpbmcgY291bnRyaWVzIHdhcyBleHBsb3JlZCwgdXNpbmcgcGFuZWwgZGF0YSBzZXJpZXMgZm9yIGZvcmVpZ24gYWlkLCB3aGlsZSBhY2NvdW50aW5nIGZvciByZWdpb25hbCBkaWZmZXJlbmNlcyBpbiBBc2lhbiwgQWZyaWNhbiwgTGF0aW4gQW1lcmljYW4sIGFuZCB0aGUgQ2FyaWJiZWFuIGNvdW50cmllcyBhcyB3ZWxsIGFzIHRoZSBkaWZmZXJlbmNlcyBpbiBpbmNvbWUgbGV2ZWxzLCB0aGUgcmVzdWx0cyBvZiB0aGlzIHN0dWR5IGFsc28gaW5kaWNhdGUgdGhhdCBmb3JlaWduIGFpZCBoYXMgbWl4ZWQgZWZmZWN0cyBvbiBlY29ub21pYyBncm93dGggaW4gZGV2ZWxvcGluZyBjb3VudHJpZXMuDQoNClxiZWdpbntmbHVzaHJpZ2h0fQ0KRWthbmF5YWtlLCBFLiAmIENoYXRybmEsIERhc2hhLiAoMjAxMCkuIFRoZSBlZmZlY3Qgb2YgZm9yZWlnbiBhaWQgb24gZWNvbm9taWMgZ3Jvd3RoIGluIGRldmVsb3BpbmcgY291bnRyaWVzLiBKb3VybmFsIG9mIEludGVybmF0aW9uYWwgQnVzaW5lc3MgYW5kIEN1bHR1cmFsIFN0dWRpZXMuIDMuDQpcZW5ke2ZsdXNocmlnaHR9DQoNCg0KVGhpcyBzdHVkeSBleGFtaW5lcyB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGZvcmVpZ24gYWlkLCBpbnN0aXR1dGlvbmFsIHN0cnVjdHVyZSwgYW5kIGVjb25vbWljIHBlcmZvcm1hbmNlIGZvciA4MCBjb3VudHJpZXMgaW4gRXVyb3BlLCBBbWVyaWNhLCBBZnJpY2EsIGFuZCBBc2lhLiBJdCBpcyBmb3VuZCB0aGF0IG9mZmljaWFsIGRldmVsb3BtZW50IGFzc2lzdGFuY2UgYW5kIHRoZSBxdWFsaXR5IG9mIGluc3RpdHV0aW9uYWwgc3RydWN0dXJlIGluIHRoZSBzYW1wbGUgY291bnRyaWVzIGFmZmVjdCBlY29ub21pYyBncm93dGggcG9zaXRpdmVseS4NCg0KXGJlZ2lue2ZsdXNocmlnaHR9DQpIYXlhbG/En2x1LCBQxLFuYXIuICgyMDIzKS4gRm9yZWlnbiBBaWQsIEluc3RpdHV0aW9ucywgYW5kIEVjb25vbWljIFBlcmZvcm1hbmNlIGluIERldmVsb3BpbmcgQ291bnRyaWVzLiBFc2tpxZ9laGlyIE9zbWFuZ2F6aSDDnG5pdmVyc2l0ZXNpIMSwa3Rpc2FkaSB2ZSDEsGRhcmkgQmlsaW1sZXIgRGVyZ2lzaS4gMTguIDc0OC03NjUuIDEwLjE3MTUzL29ndWlpYmYuMTI3NzM0OC4gDQpcZW5ke2ZsdXNocmlnaHR9DQoNCiMgTG9hZGluZyBsaWJyYXJpZXMNCg0KU29tZSBsaWJyYXJpZXMgYW5kIHBhY2thZ2VzIHVzZWQgZm9yIGRhdGEgbWFuaXB1bGF0aW9uIGFuZCBkYXRhIHNjcmFwcGluZw0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKSAjIGkgZG9uJ3QgdGhpbmsgScK0bGwgdXNlIHRoaXMgL3INCmxpYnJhcnkoV0RJKSAgICAgICAjIGZvciBXb3JsZCBCYW5rIGRhdGEgYWNjZWRpbmcgKG1vc3RseSBjb3VudHJ5IGNvZGUgbmFtZXMpDQpsaWJyYXJ5KHJlYWR4bCkgICAgIyBmb3IgZXhjZWwgZmlsZXMgcmVhZGluZw0KbGlicmFyeShyZWFkcikgICAgICMgZm9yIGNzdiBmaWxlcyByZWFkaW5nDQpsaWJyYXJ5KHZpc2RhdCkgICAgIyBmb3IgZGF0YSB2aXN1YWxpemF0aW9uDQpsaWJyYXJ5KHBsb3RseSkgICAgIyBmb3IgcGxvdHMNCmxpYnJhcnkocHVycnIpICAgICAjIGZvciBtYXAgZnVuY2l0b24NCmBgYA0KDQojIEdhdGhlcmluZyBEYXRhDQoNCkRhdGEgZm9yIGxvdyBpbmNvbWUgY291bnRyaWVzIHdpbGwgYmUgdXNlZCwgYXMgY2F0ZWdvcml6ZWQgYnkgdGhlIFdvcmxkIEJhbmsgdGhlcmUgYXJlIDI2IExvdyBpbmNvbWUgY291bnRyaWVzIGFuZCA1MSBMb3dlciBtaWRkbGUgaW5jb21lIGNvdW50cmllcw0KDQpgYGB7cn0NCmNvdW50cnlfY2xhc3MgPC0gcmVhZF9leGNlbCgiQ0xBU1MueGxzeCIpDQoNCmNvdW50cnlfY2xhc3MgJT4lDQogIGZpbHRlcighaXMubmEoUmVnaW9uKSwgIWlzLm5hKGBJbmNvbWUgZ3JvdXBgKSkgJT4lDQogIGdyb3VwX2J5KGBJbmNvbWUgZ3JvdXBgKSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50cmllcyA9IG4oKSkNCmBgYA0KDQpIZXJlIGFyZSBsaXN0ZWQgY291bnRyaWVzIHRvIHVzZToNCg0KYGBge3J9DQpteV9jb3VudHJpZXMgPC0gY291bnRyeV9jbGFzcyAlPiUNCiAgZmlsdGVyKCFpcy5uYShSZWdpb24pLCBgSW5jb21lIGdyb3VwYCAlaW4lIGMoJ0xvdyBpbmNvbWUnLCAnTG93ZXIgbWlkZGxlIGluY29tZScpKSAlPiUNCiAgc2VsZWN0KENvZGUpDQpgYGANCg0KSGVyZSB3ZSBnZXQgdGhlIHJlc3BlY3RpdmUgaXNvMmMgbmFtZXMNCg0KYGBge3J9DQpteV9jb3VudHJpZXMkaXNvMmMgPC0gV0RJX2RhdGEkY291bnRyeSAlPiUNCiAgZmlsdGVyKGlzbzNjICVpbiUgbXlfY291bnRyaWVzJENvZGUpICU+JQ0KICAuJGlzbzJjDQpgYGANCg0KRGF0YSBmcm9tIHRoZSBXb3JsZCBCYW5rIEFQSSBhbmQgdGhlIEh1bWFuIERldmVsb3BtZW50IFJlcG9ydHMgQVBJIGlzIGRvd2xvYWRlZCBieSB0aGUgdXNhZ2Ugb2YgUHl0aG9uIFNjcmlwdHMuDQpUaGV5IGFyZSBzdG9yZWQgYXMgY3N2IGZpbGVzIGFuZCB0aGVuIGxvYWRlZCBoZXJlOg0KDQojIyBIREkNCg0KYGBge3J9DQpkYXRvc19IREkgPC0gcmVhZF9jc3YoImRhdG9zX3B5dGhvbl9IREkuY3N2IiwgY29sX25hbWVzID0gYygnQ29kZScsICdpc28yYycsICdpbmRpY2F0b3InLCAneWVhcicsICd2YWx1ZScpLCANCiAgICAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBsaXN0KGNvbF9jaGFyYWN0ZXIoKSwgY29sX2NoYXJhY3RlcigpLCBjb2xfY2hhcmFjdGVyKCksIGNvbF9kb3VibGUoKSwgY29sX2RvdWJsZSgpKSkNCg0KaGRpX2luZGljYXRvcnMgPC0gZGF0b3NfSERJICU+JSBkaXN0aW5jdChpbmRpY2F0b3IpICU+JSAuJGluZGljYXRvcg0KYGBgDQoNCiMjIE9EQQ0KDQpgYGB7cn0NCm9kYV9pbmRpY2F0b3JzIDwtIGMoDQonRFRfT0RBX0FMTERfQ0QnLA0KJ0RUX09EQV9BTExEX0tEJywNCidEVF9PREFfT0FUTF9DRCcsDQonRFRfT0RBX09BVExfS0QnLA0KJ0RUX09EQV9PREFUX0NEJywNCidEVF9PREFfT0RBVF9HSV9aUycsDQonRFRfT0RBX09EQVRfR05fWlMnLA0KJ0RUX09EQV9PREFUX0tEJywNCidEVF9PREFfT0RBVF9NUF9aUycsDQonRFRfT0RBX09EQVRfUENfWlMnLA0KJ0RUX09EQV9PREFUX1hQX1pTJw0KKQ0KZ29iX2luZGljYXRvcnMgPC0gYygNCidDQ19FU1QnLA0KJ0NDX05PX1NSQycsDQonQ0NfUEVSX1JOSycsDQonQ0NfUEVSX1JOS19MT1dFUicsDQonQ0NfUEVSX1JOS19VUFBFUicsDQonQ0NfU1REX0VSUicsDQonR0VfRVNUJywNCidHRV9OT19TUkMnLA0KJ0dFX1BFUl9STksnLA0KJ0dFX1BFUl9STktfTE9XRVInLA0KJ0dFX1BFUl9STktfVVBQRVInLA0KJ0dFX1NURF9FUlInLA0KJ1BWX0VTVCcsDQonUFZfTk9fU1JDJywNCidQVl9QRVJfUk5LJywNCidQVl9QRVJfUk5LX0xPV0VSJywNCidQVl9QRVJfUk5LX1VQUEVSJywNCidQVl9TVERfRVJSJywNCidSUV9FU1QnLA0KJ1JRX05PX1NSQycsDQonUlFfUEVSX1JOSycsDQonUlFfUEVSX1JOS19MT1dFUicsDQonUlFfUEVSX1JOS19VUFBFUicsDQonUlFfU1REX0VSUicsDQonUkxfRVNUJykNCg0KZGF0b3NfV0IgPC0gZGF0YS5mcmFtZShpbmRpY2F0b3IgPSBjaGFyYWN0ZXIoKSwgaXNvMmMgPSBjaGFyYWN0ZXIoKSwgeWVhciA9IGRvdWJsZSgpLCB2YWx1ZSA9IGRvdWJsZSgpKQ0KDQpzdXBwcmVzc1dhcm5pbmdzKA0KICBmb3IgKGluZGljYXRvciBpbiBjKG9kYV9pbmRpY2F0b3JzLCBnb2JfaW5kaWNhdG9ycykpIHsNCiAgICBkYXRvc19XQiA8LSByYmluZChkYXRvc19XQiwgcmVhZF9jc3YocGFzdGUoImRhdG9zX3B5dGhvbiIsIGluZGljYXRvciwgIi5jc3YiLCBzZXAgPScnKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX25hbWVzID0gYygnaW5kaWNhdG9yJywgJ2lzbzJjJywgJ3llYXInLCAndmFsdWUnKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBsaXN0KGNvbF9jaGFyYWN0ZXIoKSwgY29sX2NoYXJhY3RlcigpLCBjb2xfZG91YmxlKCksIGNvbF9kb3VibGUoKSkpKQ0KICB9DQopDQpgYGANCg0KIyBEYXRhIE1hbmlwdWxhdGlvbg0KDQpUcmFuc2Zvcm0gdGhlIGRhdGEgaW50byBhIG5ldyBzdHJ1Y3R1cmUgZm9yIGVhc2llciB1bmRlcnN0YW5kaW5nDQoNCmBgYHtyfQ0KZGF0b3NfcGFwZXIgPC0gcmJpbmQoZGF0b3NfV0IsIGRhdG9zX0hESSAlPiUgc2VsZWN0KGluZGljYXRvciwgaXNvMmMsIHllYXIsIHZhbHVlKSkgJT4lDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBpbmRpY2F0b3IsIHZhbHVlc19mcm9tID0gdmFsdWUpDQpgYGANCg0KTGV0cyBjaGVjayB3aGljaCBkYXRhIGlzIG1pc3NpbmcuLi4NCg0KYGBge3J9DQp2aXNfZGF0KGRhdG9zX3BhcGVyICU+JSBzZWxlY3QoYWxsX29mKGdzdWIoIl8iLCAiLiIsIG9kYV9pbmRpY2F0b3JzKSkpKSANCiAgIyBEVC5PREEuT0FUTC5DRCBhbmQgRFQuT0RBLk9BVEwuS0QgbWlzc2luZyBmb3IgYWxsIGNvdW50cmllcyBhbmQgeWVhcnMNCiAgIyBEVC5PREEuT0RBVC5HSS5aUywgRFQuT0RBLk9EQVQuR04uWlMsIERULk9EQS5PREFULk1QLlpTIGFuZCBEVC5PREEuT0RBVC5YUC5aUyBhbHNvIGhhcyBzb21lIG1pc3NpbmcgdmFsdWVzDQogICMgVGhlcmUgaXMgYSBjb3VwbGUgb2YgY291bnRyaWVzIHRoYXQgaGFzIHNvbWUgbWlzc2luZyB2YWx1ZXMgZm9yIHNvbWUgZXhhY3QgeWVhcnMNCmBgYA0KYGBge3J9DQp2aXNfZGF0KGRhdG9zX3BhcGVyICU+JSBhcnJhbmdlKHllYXIpICU+JQ0KICAgICAgICAgIHNlbGVjdChhbGxfb2YoZ3N1YigiXyIsICIuIiwgZ29iX2luZGljYXRvcnMpKSkpIA0KICAjIEl0IHNlZW1zIHRoYXQgc29tZSB5ZWFycyBhcmUgbWlzc2luZyBoZXJlLCBzaG91bGQgd2UgdGFrZSBmcm9tIChhbG1vc3QpIHRoZSBoYWxmIGFuZCB1cHdhcmQ/IA0KYGBgDQpgYGB7cn0NCnZpc19kYXQoZGF0b3NfcGFwZXIgJT4lDQogICAgICAgICAgc2VsZWN0KGFsbF9vZihoZGlfaW5kaWNhdG9ycykpKSANCiAgIyBhYnIsIGNvMl9wcm9kLCBsZSwgbGVfZiwgbGVfbSwgbW1yIHNlZW1zIGxpa2UgaGFzIGFsbCB0aGUgeWVhcnMsIGJ1dC4uLiBkb2Vzbid0IGhkaT8gDQpgYGANCg0KYGBge3J9DQp2aXNfZGF0KGRhdG9zX3BhcGVyICU+JSBhcnJhbmdlKHllYXIpICU+JSBzZWxlY3QoaGRpKSkgDQogICMgaGRpIG1pc3NpbmcgaW4gdmFyaW91cyBjb3VudHJpZXMgYW5kIHllYXJzLi4uIHdoYXQgZG8gd2UgZG8/DQpgYGANClRha2luZyBpbnRvIGFjY291bnQgdGhlIG1pc3NpbmcgZGF0YSBsZXTCtHMgc2VsZWN0IGEgc21hbGxlciBzYW1wbGUgdG8gdGVzdA0KYGBge3J9DQpkYXRvc19wYXBlciAlPiUgZmlsdGVyKGlzLm5hKERULk9EQS5BTExELkNEKSkgIyMgQ3VscHJpdCBpcyBTUyAoU291dGggU3VkYW4pIGFuZCBaVyAoWmltYmFid2UpIHRoZXkgaGF2ZSBhbG1vc3Qgbm8gT0RBIGFuZA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIEdPQiBpbmRpY2F0b3JzDQpkYXRvc19wYXBlciAlPiUgZmlsdGVyKCFpc28yYyAlaW4lIGMoJ1NTJywgJ1pXJykpICU+JSBmaWx0ZXIoaXMubmEoQ0MuRVNUKSkgJT4lIGdyb3VwX2J5KHllYXIpICU+JSBzdW1tYXJpc2UodGltZXMgPSBuKCkpDQogICMgaXQgc2VlbXMgdGhhdCAxOTk1LCAxOTk3LCAxOTk5IGFuZCAyMDAxIGRpZG4ndCBtZWFzdXJlIGdvdmVybmFuY2UgaW5kaWNhdG9ycyBhdCBhbGwNCiAgIyAxOTk2LCAxOTk4LCAyMDAwLCAyMDAyIGFuZCAyMDAzIGhhcyBzb21lIG1pc3NpbmcgY291bnRyaWVzLCBpdCBzZWVtcyBsZXRzIHRha2UgYSBsb29rDQpkYXRvc19wYXBlciAlPiUgYXJyYW5nZSh5ZWFyKSAlPiUgZmlsdGVyKCFpc28yYyAlaW4lIGMoJ1NTJywgJ1pXJyksICF5ZWFyICVpbiUgYygxOTk1LCAxOTk3LCAxOTk5LCAyMDAxKSkgJT4lDQogICAgICAgICAgICAgICAgZmlsdGVyKGlzLm5hKENDLkVTVCkpICMgRk0gKE1pY3JvbmVzaWEpLCBLSSAoS2lyaWJhdGkpIGFuZCBUTCAoVGltb3ItTGVzdGUpIGRpZG50IGhhdmUgR09CIGluIHRob3NlIHllYXJzDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYWxzbyBDViAoQ2FibyBWZXJkZSkgYW5kIFNCIChTb2xvbW9uIElzbGFuZHMpIGRpZG4ndCByZWdpc3RlciBzb21lIEdPQiBpbiAyMDAwIC0gMDMNCmBgYA0KTm93IGxldHMgdmlldyBkYXRhIGFnYWluIHdpdGggdGhvc2UgZmlsdGVycw0KYGBge3J9DQpkYXRvc19wYXBlciAlPiUgDQogICAgICAgICAgYXJyYW5nZShpc28yYykgJT4lIA0KICAgICAgICAgIGZpbHRlcighaXNvMmMgJWluJSBjKCdTUycsICdaVycsICdCVCcsICdFUicsICdHVycsICdLUCcsICdMQicsICdORycsICdQUycsICdTTycsICdWVScsICdGTScsICdLSScsICdUTCcpLCANCiAgICAgICAgICAgICAgICAgIXllYXIgJWluJSBjKDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTksIDIwMDEpKSAlPiUNCiAgICAgICAgICBzZWxlY3QoaXNvMmMsIHllYXIsIGhkaSwNCiAgICAgICAgICAgICAgICAgYWxsX29mKGdzdWIoIl8iLCAiLiIsIGdvYl9pbmRpY2F0b3JzKSkNCiAgICAgICAgICAgICAgICAgKSAlPiUNCiAgICAgICAgIGZpbHRlcihpcy5uYShHRS5FU1QpKSAjJT4lDQogICAgICAgICAjIGdyb3VwX2J5KHllYXIpICU+JQ0KICAgICAgICAgIyBzdW1tYXJpc2UodGltZXMgPSBuKCkpIA0KIyAxOTk2IGFuZCAxOTk4IGFyZSB0cm91Ymxlc29tZSwgc28gbGV0cyBzdGFydCBpbiAyMDAwDQojIEJUIChCaHV0YW4pLCBFUiAoRXJpdHJlYSksIEdXIChHdWluZWEtQmlzc2F1KSwgS1AgKE5vcnRoIEtvcmVhKSwgTEIgKExlYmFub24pLCBORyAoTmlnZXJpYSksIFBTIChQYWxlc3RpbmUpLCBTTyAoU29tYWxpYSksDQojIFZVIChWYW51YXR1KSBhcmUgdGhlIGNvdW50cmllcyB3aXRob3V0IGhkaQ0KYGBgDQoNCmBgYHtyfQ0KdmlzX2RhdChkYXRvc19wYXBlciAlPiUgDQogICAgICAgIGZpbHRlcighaXNvMmMgJWluJSBjKCdTUycsICdaVycsICdCVCcsICdFUicsICdHVycsICdLUCcsICdMQicsICdORycsICdQUycsICdTTycsICdWVScsICdGTScsICdLSScsICdUTCcsICdDVicsICdTQicpLA0KICAgICAgICAgICAgICAgIXllYXIgJWluJSBjKDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsIDE5OTksIDIwMDAsIDIwMDEpKSAlPiUNCiAgICAgICAgc2VsZWN0KGlzbzJjLCB5ZWFyLCBoZGksIERULk9EQS5BTExELkNELCBEVC5PREEuQUxMRC5LRCwgRFQuT0RBLk9EQVQuQ0QsIERULk9EQS5PREFULktELCBEVC5PREEuT0RBVC5QQy5aUywNCiAgICAgICAgICAgICAgIGFsbF9vZihnc3ViKCJfIiwgIi4iLCBnb2JfaW5kaWNhdG9ycykpDQogICAgICAgICAgICAgICApKQ0KYGBgDQpGcm9tIDE5MjUgdG8gMTA5OCByb3dzIGh1aC4uLiBpIGRvbid0IGtub3cuLi4NCmBgYHtyfQ0KZGF0b3NfbW9kZWwgPC0gZGF0b3NfcGFwZXIgJT4lIA0KICAgICAgICBmaWx0ZXIoIWlzbzJjICVpbiUgYygnU1MnLCAnWlcnLCAnQlQnLCAnRVInLCAnR1cnLCAnS1AnLCAnTEInLCAnTkcnLCAnUFMnLCAnU08nLCAnVlUnLCAnRk0nLCAnS0knLCAnVEwnLCAnQ1YnLCAnU0InKSwNCiAgICAgICAgICAgICAgICF5ZWFyICVpbiUgYygxOTk1LCAxOTk2LCAxOTk3LCAxOTk4LCAxOTk5LCAyMDAwLCAyMDAxKSkgJT4lDQogICAgICAgIHNlbGVjdChpc28yYywgeWVhciwgaGRpLCBEVC5PREEuQUxMRC5DRCwgRFQuT0RBLkFMTEQuS0QsIERULk9EQS5PREFULkNELCBEVC5PREEuT0RBVC5LRCwgRFQuT0RBLk9EQVQuUEMuWlMsDQogICAgICAgICAgICAgICBhbGxfb2YoZ3N1YigiXyIsICIuIiwgZ29iX2luZGljYXRvcnMpKQ0KICAgICAgICAgICAgICAgKQ0KYGBgDQoNCkxldCdzIGdpdmUgaXQgYSBzaG90IHdpdGggYSBsaW5lYXIgbW9kZWwNCmBgYHtyfQ0KbW9kZWwgPC0gbG0oaGRpIH4gRFQuT0RBLkFMTEQuQ0QgKyBDQy5FU1QgKyBHRS5FU1QgKyBQVi5FU1QgKyBSUS5FU1QgKyBSTC5FU1QsIGRhdGE9ZGF0b3NfbW9kZWwpDQpzdW1tYXJ5KG1vZGVsKQ0KYGBgDQpJdCB3b3JrZWQhISENCmJ1dCBJIGp1c3QgdGhyZXcgcmFuZG9tIHZhcmlhYmxlcyBpbiB0aGVyZSwgSSB3YW50IHRvIHNlZSB0aGVpciByZWxhdGlvbnNoaXAgd2l0aCBISUQNCg0KI0RhdGEgdmlzdWFsaXphdGlvbg0KDQpgYGB7cn0NCm15X3Bsb3QgIDwtIGxpc3QoKQ0KDQpmb3IgKGNvbCBpbiBjb2xuYW1lcyhkYXRvc19tb2RlbClbNDozM10pIHsNCiAgbXlfcGxvdFtbY29sXV0gPC0gcGxvdF9seSh4ID0gZGF0b3NfbW9kZWxbW2NvbF1dLCB5ID0gZGF0b3NfbW9kZWxbWzNdXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ21hcmtlcnMnLCBuYW1lID0gcGFzdGUoY29sLCAidnMgSERJIikpICANCn0NCg0KDQpzdWJwbG90KG15X3Bsb3RbMTo1XSwgbnJvd3MgPSAyLCBtYXJnaW4gPSAwLjA1KSAlPiUgbGF5b3V0KHRpdGxlID0gJ09EQSB2cyBIREknKQ0KDQpgYGANCg0KYGBge3J9DQpzdWJwbG90KG15X3Bsb3RbNjoxMV0sIG5yb3dzID0gMiwgbWFyZ2luID0gMC4wNSkgJT4lIGxheW91dCh0aXRsZSA9ICdDQyB2cyBIREknKQ0KYGBgDQoNCmBgYHtyfQ0Kc3VicGxvdChteV9wbG90WzEyOjE3XSwgbnJvd3MgPSAyLCBtYXJnaW4gPSAwLjA1KSAlPiUgbGF5b3V0KHRpdGxlID0gJ0dFIHZzIEhESScpDQpgYGANCg0KDQpgYGB7cn0NCnN1YnBsb3QobXlfcGxvdFsxODoyM10sIG5yb3dzID0gMiwgbWFyZ2luID0gMC4wNSkgJT4lIGxheW91dCh0aXRsZSA9ICdQViB2cyBIREknKQ0KYGBgDQoNCmBgYHtyfQ0Kc3VicGxvdChteV9wbG90WzI0OjI5XSwgbnJvd3MgPSAyLCBtYXJnaW4gPSAwLjA1KSAlPiUgbGF5b3V0KHRpdGxlID0gJ1JRIHZzIEhESScpDQpgYGANCg0KYGBge3J9DQpzdWJwbG90KG15X3Bsb3RbMzBdLCBucm93cyA9IDEsIG1hcmdpbiA9IDAuMDUpICU+JSBsYXlvdXQodGl0bGUgPSAnUkwgdnMgSERJJykNCmBgYA0KDQouLi4gd2hhdCB3YXMgdGhhdD8/Pw0KSSBndWVzcyBJIGNhbnQganVzdCB0aHJvdyB0aGluZ3MgaW4gdGhlcmUgYW5kIGV4cGVjdCB0byBoYXZlIGEgZ29vZCBtb2RlbCwgSSBjYW4ndCBzZWUgYSBjbGVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGlzIHN0dWZmLCBtb3JlIHRoYW4gYmV0dGVyIGdvdmVybmFuY2UgaW5kaWNhdG9ycyBhcmUgdXN1YWxseSBhY2NvbXBhbmllZCB3aXRoIGJldHRlciBIREkgc2NvcmVzLg0KQnV0Li4uIEkgd2FzIHNheWluZyB0aGF0IEkgd2FudGVkIHRvIGZpbmQgYSByZWxhdGlvbnNoaXAgd2l0aCBIREkgY2hhbmdlcywgbm90IHRoZSBhY3R1YWwgSERJIHNjb3JlLiBTbywgSSdsbCBjb21wdXRlIGEgSERJIGNoYW5nZSBwZXIgeWVhciBwZXIgY291bnRyeSwgKGFuZCBsb3NlIDYxIHJvd3MgaW4gdGhlIHByb2Nlc3MsIHlheS4uLikNCg0KIyBEYXRhIG1hbmlwdWxhdGlvbiAyIEVsZWN0cmljIGJvb2dhbG9vDQoNCk5vdGU6IG9yaWdpbmFsbHkgSSB3YXMgZXhjbHVkaW5nIGRhdGEgZnJvbSAyMDAxLCBiZWNhdXNlIHNvbWUgY291bnRyaWVzIGRpZG4ndCBoYXZlIGdvdmVybmFuY2UgaW5kaWNhdG9ycyBmb3IgdGhhdCB5ZWFyIHBhcnRpY3VsYXJseSwgYnV0ISwgc2luY2UgSSdsbCBsb3NlIG9uZSB5ZWFyIGJ5IGNvbXB1dGluZyB0aGUgZ3Jvd3RoIGluIGhkaSBJIGNhbiBzdGlsbCB1c2UgdGhpcyB5ZWFyIGFuZCB3b250IGxvb3NlIGRhdGEgYWwgYWxsLiBTVE9OS1MhISENCg0KYGBge3J9DQpkYXRvc19tb2RlbF8yIDwtIGRhdG9zX3BhcGVyICU+JSANCiAgICAgICAgZmlsdGVyKCFpc28yYyAlaW4lIGMoJ1NTJywgJ1pXJywgJ0JUJywgJ0VSJywgJ0dXJywgJ0tQJywgJ0xCJywgJ05HJywgJ1BTJywgJ1NPJywgJ1ZVJywgJ0ZNJywgJ0tJJywgJ1RMJywgJ0NWJywgJ1NCJyksDQogICAgICAgICAgICAgICAheWVhciAlaW4lIGMoMTk5NSwgMTk5NiwgMTk5NywgMTk5OCwgMTk5OSwgMjAwMCkpICU+JQ0KICAgICAgICBzZWxlY3QoaXNvMmMsIHllYXIsIGhkaSwgRFQuT0RBLkFMTEQuQ0QsIERULk9EQS5BTExELktELCBEVC5PREEuT0RBVC5DRCwgRFQuT0RBLk9EQVQuS0QsIERULk9EQS5PREFULlBDLlpTLA0KICAgICAgICAgICAgICAgYWxsX29mKGdzdWIoIl8iLCAiLiIsIGdvYl9pbmRpY2F0b3JzKSkNCiAgICAgICAgICAgICAgICkNCg0KdmlzX2RhdChkYXRvc19tb2RlbF8yKQ0KYGBgDQoNCmBgYHtyfQ0KZGF0b3NfbW9kZWxfMyA8LSBkYXRvc19tb2RlbF8yICU+JQ0KICBhcnJhbmdlKGlzbzJjLCB5ZWFyKSAlPiUNCiAgbXV0YXRlKGhkaV9kaWZmID0gaGRpIC0gbGFnKGhkaSkpICU+JQ0KICBmaWx0ZXIoIXllYXIgJWluJSBjKDIwMDEpKQ0KDQpkYXRvc19tb2RlbF8zICU+JSBzZWxlY3QoaXNvMmMsIHllYXIsIGhkaSwgaGRpX2RpZmYpDQoNCnZpc19kYXQoZGF0b3NfbW9kZWxfMykNCmBgYA0KYW5kIGhlcmUgd2UgZ28gYWdhaW4NCmBgYHtyfQ0KbXlfcGxvdF8zICA8LSBsaXN0KCkNCg0KZm9yIChjb2wgaW4gY29sbmFtZXMoZGF0b3NfbW9kZWxfMylbNDozM10pIHsNCiAgbXlfcGxvdF8zW1tjb2xdXSA8LSBwbG90X2x5KHggPSBkYXRvc19tb2RlbF8zW1tjb2xdXSwgeSA9IGRhdG9zX21vZGVsXzNbWzM0XV0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdtYXJrZXJzJywgbmFtZSA9IHBhc3RlKGNvbCwgInZzIEhESSBkaWZmIikpICANCn0NCg0KDQpzdWJwbG90KG15X3Bsb3RfM1sxOjVdLCBucm93cyA9IDIsIG1hcmdpbiA9IDAuMDUpICU+JSBsYXlvdXQodGl0bGUgPSAnT0RBIHZzIEhESScpDQpgYGANCg0KYGBge3J9DQpzdWJwbG90KG15X3Bsb3RfM1s2OjExXSwgbnJvd3MgPSAyLCBtYXJnaW4gPSAwLjA1KSAlPiUgbGF5b3V0KHRpdGxlID0gJ0NDIHZzIEhESSBkaWZmJykNCmBgYA0KYGBge3J9DQpzdWJwbG90KG15X3Bsb3RfM1sxMjoxN10sIG5yb3dzID0gMiwgbWFyZ2luID0gMC4wNSkgJT4lIGxheW91dCh0aXRsZSA9ICdHRSB2cyBIREkgZGlmZicpDQpgYGANCg0KYGBge3J9DQpzdWJwbG90KG15X3Bsb3RfM1sxODoyM10sIG5yb3dzID0gMiwgbWFyZ2luID0gMC4wNSkgJT4lIGxheW91dCh0aXRsZSA9ICdQViB2cyBIREkgZGlmZicpDQpgYGANCg0KYGBge3J9DQpzdWJwbG90KG15X3Bsb3RfM1syNDoyOV0sIG5yb3dzID0gMiwgbWFyZ2luID0gMC4wNSkgJT4lIGxheW91dCh0aXRsZSA9ICdSUSB2cyBIREkgZGlmZicpDQpgYGANCg0KYGBge3J9DQpzdWJwbG90KG15X3Bsb3RfM1szMF0sIG5yb3dzID0gMSwgbWFyZ2luID0gMC4wNSkgJT4lIGxheW91dCh0aXRsZSA9ICdSTCB2cyBIREkgZGlmZicpDQpgYGANCg0KVGVzdGluZyBtb2RlbCB3aGlsZSB1c2luZyBoZGlfZGlmZiBhcyBkZXBlbmRlbnQgdmFyaWFibGUgKGl0IHdlbnQgYmV0dGVyIHRoYW4gZXhwZWN0ZWQpDQpgYGB7cn0NCm1vZGVsXzMgPC0gbG0oaGRpX2RpZmYgfiBEVC5PREEuQUxMRC5DRCArIENDLkVTVCArIEdFLkVTVCArIFBWLkVTVCArIFJRLkVTVCArIFJMLkVTVCwgZGF0YT1kYXRvc19tb2RlbF8zKQ0Kc3VtbWFyeShtb2RlbF8zKQ0KYGBgDQpJIGxpa2VkIHRoZSByZWxhdGlvbnNoaXAgdmlzaWJsZSBpbiB0aGUgUEVSLlJOSyBnb3YgaW5kaWNhdG9ycywgbGV0J3MgdHJ5IGEgbW9kZWwgd2l0aCB0aG9zZSB2YXJpYWJsZXMgKGl0IHdlbnQgd29yc2UgdGhhbiBleHBlY3RlZCkNCmBgYHtyfQ0KbW9kZWxfNCA8LSBsbShoZGlfZGlmZiB+IERULk9EQS5BTExELkNEICsgQ0MuUEVSLlJOSyArIEdFLlBFUi5STksgKyBQVi5QRVIuUk5LICsgUlEuUEVSLlJOSyArIFJMLkVTVCwgZGF0YT1kYXRvc19tb2RlbF8zKQ0Kc3VtbWFyeShtb2RlbF80KQ0KYGBg